# This file is part of Gehyra.
#
# Gehyra is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Gehyra is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gehyra.  If not, see <http://www.gnu.org/licenses/>.

"""
@package gehyra.entity.modules.adc_hub.py
The module which speaks ADC to DC clients.

$Id: adc_hub.py 454 2011-02-08 14:26:59Z andyhhp@gmail.com $
"""

"""
@file gehyra/entity/modules/adc_hub.py
The module which speaks ADC to DC clients.
"""

import uuid

from gehyra.common.logger import LOG
from gehyra.common.interfaces import (IEntity, IGlobalObserver)

from zope.interface import implements

from twisted.internet import reactor
from gehyra.entity.modules.Adc.AdcFactory import AdcServerFactory


class adc_hub(object):
    """ADC Hub Entity
    """
    implements(IEntity, IGlobalObserver)

    ## State ID for when no TCP conenction exists
    STATE_DISCONNECTED = 1

    def __init__(self, main, manager, name, **args):
        """Constructor.
        @param main Main gehyra object
        @param manager Entity manager object to which we belong
        @param name Name of this entity as given in the configuration.
        @param **args Dictionary of arguments
        """

        ## name of the entity
        self.name = name
        ## entity manager responsible for us
        # (not guarenteed to be self.entity_manager)
        self.manager = manager
        ## main gehyra object
        self.main = main

        if 'uuid' not in args:
            self.uuid = uuid.uuid4()
            LOG.warn("No UUID for entity '%s'.  "
                     "Creating random UUID" % self.name)

            self.main.config_manager.node["entities"][name]\
                ['args'].update({"uuid": self.uuid})

        else:

            if args['uuid'] == "OVERWRITE_ON_FIRST_RUN":
                self.uuid = uuid.uuid4()
                self.main.config_manager.node["entities"]\
                    [name+".args"].update({"uuid": self.uuid})
                LOG.info("Overwriting uuid for entity %s" % name)
            else:
                try:
                    ## uuid of the entity
                    self.uuid = uuid.UUID(args['uuid'])
                except ValueError:
                    self.uuid = uuid.uuid4()
                    LOG.warn("Badly formed UUID string found for '%s'.  "
                             "Creating random UUID" % self.name)
            del args['uuid']


        if 'port' in args:
            ## tcp port to talk to the client on - defaults to 7134
            self.port = args['port']
            del args['port']
        else:
            self.port = 7134

        LOG.critical(self.main.config_manager.node['entities'][name+".args"])


        if 'interface' in args:
            ## interface to bind to - defaults to 127.0.0.1
            self.interface = args['interface']
            del args['interface']
        else:
            self.interface = "127.0.0.1"

        for a in args:
            LOG.warn("ADC Client '%s' has received unrecognised parameter '%s'"
                     % (name, a) )

        ## current state of the hub
        self.state = self.STATE_DISCONNECTED


    def initialize(self):
        """Initialize.
        Hook us as an observer
        """
        self.main.hook_observer(self)

    def on_event(self, event):
        """Observe event.
        If we hear a startup even and are currently disconnected, start
        listening.
        """
        if event == self.main.EVENT_STARTUP:
            if self.state == self.STATE_DISCONNECTED:
                LOG.info("adc_hub entity '%s' listening on %s:%s"
                         % (self.name, self.interface, self.port))
                reactor.listenTCP(self.port, AdcServerFactory(self),
                                  interface=self.interface)

    def on_state(self, state):
        """Observe state change."""
